<?php

namespace App\DTOS;
use Illuminate\Support\Str;
abstract class BaseDTO
{
    /**
     * @var int 当前页数
     */
    protected int $page = 1;
    /**
     * @var int 每页条数
     */
    protected int $limit = 10;


    /** 类的属性映射类方法 利用反射映射实例化类并且映射类中的 私有属性 ,需要类具有getter setter
     * @param string $class
     * @param array $data
     * @return \App\DTOS\BaseDTO
     */
    public function __construct(array $data=[])
    {
        $reflectionClass = new \ReflectionClass($this);
        $properties = $reflectionClass->getProperties();
        foreach($properties as $item){
            $propertyName = $item->name;
            $setMethod = 'set'.ucfirst(Str::camel($propertyName));
            if (isset($data[$propertyName])){
                $value = $data[$item->name];
                if (method_exists($this,$setMethod)){
                    $this->$setMethod($value); //设置属性
                }
            }
        }
    }

    /**
     * @return int
     */
    public function getPage(): int
    {
        return $this->page;
    }

    /**
     * @param int $page
     */
    public function setPage(int $page): void
    {
        $this->page = $page;
    }

    /**
     * @return int
     */
    public function getLimit(): int
    {
        return $this->limit;
    }

    /**
     * @param int $limit
     */
    public function setLimit(int $limit): void
    {
        $this->limit = $limit;
    }

    /** 类的属性映射类方法 利用反射映射实例化类并且映射类中的 私有属性 ,需要类具有getter setter
     * @param string $class
     * @param array $data
     * @return BaseDTO
     */
    protected function map($data=[]){
        $reflectionClass = new \ReflectionClass($this);
        $properties = $reflectionClass->getProperties();
        foreach($properties as $item){
            $propertyName = $item->name;
            if (isset($data[$propertyName])){
                $value = $data[$item->name];
                $setMethod = 'set'.ucfirst(Str::camel($propertyName));
                if (method_exists($this,$setMethod)){
                    $this->$setMethod($value); //设置属性
                }
            }
        }
        return $this;
    }


    /**
     * @return array
     */
    public function toArray(){
        $reflectionClass = new \ReflectionClass($this);
        $properties = $reflectionClass->getProperties();
        $array = [];
        foreach($properties as $item){
            $propertyName = $item->name;
            $getMethod = 'get'.ucfirst(Str::camel($propertyName));
            if (method_exists($this,$getMethod)){
                $array[$propertyName] = $this->$getMethod();
            }
        }

        return $array;
    }

    /**
     * @return string
     */
    public function toJsonString(){
        return json_encode($this->toArray());
    }

}
